import exceptions.NoJuegaException
import exceptions.YaJuegaException
import futbol5.Condicional
import futbol5.Estandar
import futbol5.Jugador
import futbol5.Partido
import futbol5.PorEdad
import futbol5.SiNoJuega
import futbol5.SonTantosOMenos
import observers.Mail
import observers.MailAMuchos
import observers.MailAdmin
import observers.MessageSender
import org.junit.Before
import org.junit.Test

import static org.mockito.Matchers.*
import static org.mockito.Mockito.*
import static org.junit.Assert.*
import futbol5.Administrador


//import futbol5.Solidario

class TestCondiciones {
	
	var Partido partido
	var Jugador ale
	var Jugador eric
	var Jugador daiana
	var SiNoJuega condicionAleJugador
	var PorEdad condicionAleEdad
	var SonTantosOMenos condicionAleEquipo
	var Condicional tipoAle
	var Administrador adminPartidos

	
	//var Estandar tipoEric
		
	@Before
	def void init(){
		partido = new Partido
		ale = new Jugador
		eric = new Jugador
		daiana = new Jugador
		
		adminPartidos = new Administrador
		
		//tipoEric = new Estandar
		tipoAle = new Condicional
		ale.categoria = tipoAle
		//eric.categoria = tipoEric
		
		eric.categoria = new Estandar
		daiana.categoria = new Estandar
		
		partido.agregarJugador(eric)
		
	}
	
	
	@Test
	def void TestJugadorNoQuerido(){
		condicionAleJugador = new SiNoJuega
		tipoAle.condicion = condicionAleJugador
		condicionAleJugador.jugadorNoQuerido = eric
		assertFalse(ale.juegoEn(partido))
	}
		
	@Test
	def void TestJugadorQuerido(){
		condicionAleJugador = new SiNoJuega
		tipoAle.condicion = condicionAleJugador
		condicionAleJugador.jugadorNoQuerido = daiana
		assertTrue(ale.juegoEn(partido))
	}
	
	@Test 
	def void TestEdadFalse(){
		eric.edad = 13
		condicionAleEdad = new PorEdad
		tipoAle.condicion = condicionAleEdad
		condicionAleEdad.edadMinima = 15
		assertFalse(ale.juegoEn(partido))
	}
	
	@Test 
	def void TestEdadTrue(){
		eric.edad = 18
		condicionAleEdad = new PorEdad
		tipoAle.condicion = condicionAleEdad
		condicionAleEdad.edadMinima = 15
		assertTrue(ale.juegoEn(partido))
	}
	
	@Test 
	def void TestEquipoChico(){
		condicionAleEquipo = new SonTantosOMenos
		tipoAle.condicion = condicionAleEquipo
		condicionAleEquipo.cantidadMaxima = 2
		assertTrue(ale.juegoEn(partido))
	}
	
	@Test
	def void TestEquipoGrande(){
		condicionAleEquipo = new SonTantosOMenos
		tipoAle.condicion = condicionAleEquipo
		condicionAleEquipo.cantidadMaxima = 2
		partido.agregarJugador(daiana)
		assertFalse(ale.juegoEn(partido))
	}
	

	@Test (expected=typeof(YaJuegaException))
	def void yaJuega(){
		partido.agregarJugador(eric)
	}
	
	@Test (expected=typeof(NoJuegaException))
	def void noJuega(){
		condicionAleJugador = new SiNoJuega
		tipoAle.condicion = condicionAleJugador
		condicionAleJugador.jugadorNoQuerido = daiana
		partido.agregarJugador(ale)
		partido.agregarJugador(daiana)
	}
 
 @Test
	 def void testEnvioAdminTodosConfirmados(){
	 	
 	 	var mockedMailSender = mock(typeof(MessageSender))
 	 	
 	 	var mailAdministrador = new MailAdmin(mockedMailSender)
 	 		
 	 	mailAdministrador.llegueADiez()
	 	
	 	verify(mockedMailSender, times(1)).send(any(typeof(Mail)))
	 	
	 }
	
	@Test
	 def void testEnvioAdminSeBajaron(){
	 	
 	 	var mockedMailSender = mock(typeof(MessageSender))
 	 	
 	 	var mailPorBaja = new MailAdmin(mockedMailSender)
 	 		
 	 	mailPorBaja.seBajoAlguno()
	 	
	 	verify(mockedMailSender, times(1)).send(any(typeof(Mail)))
	 	
	 }
	
	 
	@Test
	def void testATodos(){
		partido.agregarJugador(daiana)
		ale.categoria = new Estandar
		partido.agregarJugador(ale)
		
		var mockedMailSender = mock(typeof(MessageSender))
 	 	
 	 	var mailATodos = new MailAMuchos(mockedMailSender)
 	 		
 	 	mailATodos.avisaQueJuego(partido.jugadores)
	 	
	 	verify(mockedMailSender, times(3)).send(any(typeof(Mail)))
	}
 
 	@Test
 	def void testRecomendacionRechazada(){
 		ale.categoria = new Estandar
 		ale.recomendarJugador(daiana,adminPartidos)
 		var b = adminPartidos.solicitudes.iterator.next
 		adminPartidos.rechazar(b)
 		assertEquals(1,adminPartidos.solicitudesRechazadas.size())
 		
 	}
 	
 	@Test
 	def void testRecomendacionAceptada(){
 		eric.recomendarJugador(daiana,adminPartidos)
 		var b = adminPartidos.solicitudes.iterator.next
 		adminPartidos.aceptar(b)
 		assertTrue(adminPartidos.jugadoresPosibles.contains(daiana))
 		}
 
	@Test
	def void testPuntuacionAceptada(){
		daiana.calificar(ale,8,"bastante bien",adminPartidos)
		var b = adminPartidos.solicitudes.iterator.next
		adminPartidos.aceptar(b)
		assertEquals(1,ale.puntuaciones.size())
	} 
	
	@Test
	def void testPuntuacionRechazada(){
		eric.calificar(ale,4,"no tan bueno",adminPartidos)
		var b = adminPartidos.solicitudes.iterator.next
		adminPartidos.rechazar(b)
		assertEquals(1,eric.puntuaciones.size())
	}
}